import express from "express";
import path from "path";
import fs from "fs";
var router = express.Router();
import formidable from "formidable";
import { DB } from "../api.js";
var nedb = new DB("./nedb/db/app.db", [{ fieldName: "applicationName", unique: true }]);
export { nedb };
import { nedbClassic } from "./appClassic.js";

import compressing from "compressing";

function copyTemp(source, target) {
  if (fs.existsSync(target)) {
    fs.rmdirSync(target, { recursive: true }); //目标目录存在,删除目标目录
  }
  if (!fs.existsSync(target)) {
    fs.mkdirSync(target, { recursive: true }); //目标目录不存在,创建目标目录
  }
  function copyDir(srcDir, desDir) {
    fs.readdir(srcDir, { withFileTypes: true }, (err, files) => {
      for (const file of files) {
        //判断是否为文件夹
        if (file.isDirectory()) {
          const dirS = path.resolve(srcDir, file.name);
          const dirD = path.resolve(desDir, file.name);
          //判断是否存在dirD文件夹
          if (!fs.existsSync(dirD)) {
            fs.mkdir(dirD, (err) => {
              if (err) console.log(err);
            });
          }
          copyDir(dirS, dirD);
        } else {
          const srcFile = path.resolve(srcDir, file.name);
          const desFile = path.resolve(desDir, file.name);
          fs.copyFileSync(srcFile, desFile);
          // console.log(file.name + " 拷贝成功");
        }
      }
    });
  }
  copyDir(source, target);
}

// copyTemp("./appStatic/visualApp", "./appStatic/_temp/appTemplate"); //拷贝应用模板
// copyTemp("./appStatic/visualAppLib", "./appStatic/_temp/appSdkTemplate"); //拷贝应用sdk模板

//下载应用
router.get("/download/:id", function (req, res, next) {
  var params = req.params;
  nedb.findOne(params).then((result) => {
    if (result && result.data) {
      var appConfigPath = "./appStatic/_temp/appTemplate/assets/app.config.js";
      if (fs.existsSync(appConfigPath)) {
        fs.rmSync(appConfigPath);
        // console.log("删除/app.config.js");
      }
      let dir = "./appStatic/_temp";
      // if (!fs.existsSync(dir)) {
      //   fs.mkdirSync(dir, { recursive: true });
      // }
      var appId = result.data._id;
      var appName = result.data.applicationName;
      var zipFileName = "" + `${appName}.zip`;
      var zipFilePath = `${dir}/${appName}.zip`;

      function handleError(error) {
        // console.error("[应用打包异常]", error);
        res.json({ code: -1, message: "应用下载失败", error });
      }

      function handleFinish() {
        // console.log("[应用打包完成]", zipFileName, path.resolve(zipFilePath));
        // res.json({ zipFilePath });
        res.download(zipFilePath, zipFileName, (error) => {
          // console.log("[发送应用结束]");
          error && console.error("[发送应用 error]", error);
        });
      }

      // if (fs.existsSync(zipFilePath)) {
      //   return handleFinish(); //压缩包已存在直接发送压缩包(需要在保存应用的时候删除压缩包以同步压缩包内容)
      // }

      // console.log("[准备打包应用]", appId);

      var zipStream = fs.createWriteStream(zipFilePath);

      var streamDir = new compressing.zip.Stream();
      streamDir.addEntry("./appStatic/_temp/appTemplate", {
        ignoreBase: true
      });
      streamDir.addEntry(`./appStatic/app/${appId}`, { relativePath: "app" });
      let str =
        "window.VisualApp=" +
        JSON.stringify(result.data, null, 2) +
        `;\n
        (function (root, obj) {
          if (typeof exports === "object" && typeof module === "object") module.exports = obj;
          else if (typeof define === "function" && define.amd) define([], obj);
          else if (typeof exports === "object") exports["VisualApp"] = obj;
          else root["VisualApp"] = obj;
        })(typeof self !== "undefined" ? self : this, window.VisualApp);
        `;
      streamDir.addEntry(Buffer.from(str), {
        relativePath: "assets/app.config.js"
      });
      streamDir.on("error", handleError).pipe(zipStream).on("error", handleError).on("finish", handleFinish);
    }
  });
});

//下载应用sdk
router.get("/download/sdk/:id", function (req, res, next) {
  var params = req.params;

  nedb.findOne(params).then((result) => {
    if (result && result.data) {
      var appConfigPath = "./appStatic/_temp/appSdkTemplate/public/assets/app.config.js";
      if (fs.existsSync(appConfigPath)) {
        fs.rmSync(appConfigPath);
        // console.log("删除/app.config.js");
      }
      let dir = "./appStatic/_temp";

      var appId = result.data._id;
      var appName = result.data.applicationName;
      var zipFileName = "" + `${appName}.sdk.zip`;
      var zipFilePath = `${dir}/${appName}.sdk.zip`;

      function handleError(error) {
        // console.error("[应用打包异常]", error);
        res.json({ code: -1, message: "应用下载失败", error });
      }

      function handleFinish() {
        // console.log("[应用打包完成]", zipFileName, path.resolve(zipFilePath));
        // res.json({ zipFilePath });
        res.download(zipFilePath, zipFileName, (error) => {
          // console.log("[发送应用结束]");
          error && console.error("[发送应用 error]", error);
        });
      }

      // if (fs.existsSync(zipFilePath)) {
      //   return handleFinish(); //压缩包已存在直接发送压缩包(需要在保存应用的时候删除压缩包以同步压缩包内容)
      // }

      // console.log("[准备打包应用]", appId);

      var zipStream = fs.createWriteStream(zipFilePath);

      var streamDir = new compressing.zip.Stream();
      streamDir.addEntry("./appStatic/_temp/appSdkTemplate", {
        ignoreBase: true
      });
      streamDir.addEntry(`./appStatic/app/${appId}`, {
        relativePath: "public/app"
      });
      let str =
        "window.VisualApp=" +
        JSON.stringify(result.data, null, 2) +
        `;\n
        (function (root, obj) {
          if (typeof exports === "object" && typeof module === "object") module.exports = obj;
          else if (typeof define === "function" && define.amd) define([], obj);
          else if (typeof exports === "object") exports["VisualApp"] = obj;
          else root["VisualApp"] = obj;
        })(typeof self !== "undefined" ? self : this, window.VisualApp);
        `;
      streamDir.addEntry(Buffer.from(str), {
        relativePath: "public/assets/app.config.js"
      });
      streamDir.on("error", handleError).pipe(zipStream).on("error", handleError).on("finish", handleFinish);
    }
  });
});

//保存文件
router.post("/upload/:id/:path", function (req, res, next) {
  try {
    var params = req.params || {};
    let dirParent = "./appStatic/";
    let dirFile = `./app/${params.id}/${params.path}`;
    let dir = `${dirParent}/${dirFile}`;
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    var form = new formidable.IncomingForm();
    // form.encoding = "utf-8"; // 设置编码
    form.uploadDir = dir; // 设置上传目录
    form.keepExtensions = true; // 保留后缀
    form.maxFieldsSize = 2 * 1024 * 1024; // 文件大小 （2 * 1024 * 1024 默认20M）
    form.parse(req, function (error, fields, files) {
      // console.log(error, fields, files);
      let fileName = undefined;
      if (files && files.file) {
        var originalFilename = files.file.originalFilename;
        fileName = `${dirFile}/${originalFilename}`; //文件名
        if (fs.existsSync(`${dirParent}/${fileName}`)) {
          let arr = originalFilename.split("");
          let i = originalFilename.lastIndexOf(".");
          i < 0 && (i = fileName.length - 1);
          var newFilename = files.file.newFilename;
          arr[i] = `_${newFilename}` + arr[i];
          fileName = `${dirFile}/${arr.join("")}`;
        }
        fs.renameSync(files.file.filepath, `${dirParent}/${fileName}`); //重命名
      }
      res.json({
        code: !error ? 200 : -1,
        message: !error ? "文件上传成功" : "文件上传失败",
        data: fileName
      });
    });
  } catch (error) {
    console.log(error);
    res.json({
      code: -1,
      message: "文件上传异常",
      error: error.message
    });
  }
});
//查询目录下的文件列表
router.get("/file/:id/:path", function (req, res, next) {
  try {
    var params = req.params || {};
    let dirParent = "./appStatic/";
    let dir = `./app/${params.id}/${params.path}`;
    var files = fs.existsSync(`${dirParent}${dir}`) ? fs.readdirSync(`${dirParent}${dir}`) : [];
    // console.log(files);
    var fileList = [];
    files.forEach((item, i) => {
      var filePath = path.join(dir, item);
      var statPath = path.join(dirParent, filePath);
      var stat = fs.statSync(statPath);
      // console.log(stat, statPath, filePath);
      if (stat.isDirectory()) {
      } else {
        fileList.push(`${dir}/${item}`);
      }
    });
    // console.log(fileList);
    res.json({
      code: fileList.length ? 200 : -1,
      message: fileList.length ? "目录解析成功" : "当前目录没有文件",
      data: fileList
    });
  } catch (error) {
    res.json({
      code: -1,
      message: "目录解析异常",
      error
    });
  }
});

//应用收藏
router.get("/change/classic", function (req, res, next) {
  var params = req.query;
  params && params.id && !params._id && (params._id = params.id); //TODO 需要删除

  nedb.findOne(params).then((result) => {
    var data = result.data;
    let oldId = data._id;
    delete data.id;
    delete data._id;
    data.applicationName = params.applicationName;

    nedbClassic.insert(data).then((resultCopy) => {
      if (resultCopy.data) {
        var doc = resultCopy.data;
        var docStr = JSON.stringify(doc).replace(new RegExp(oldId, "g"), doc._id);
        var docReplace = JSON.parse(docStr);
        nedbClassic.update(docReplace).then((result1) => {
          if (result1.code == nedbClassic.CODE_SUCCESS) {
            copyTemp(`./appStatic/app/${oldId}`, `./appStatic/app/${doc._id}`);
            result1.message = "应用收藏成功";
          }
          res.json(result1);
        });
      } else {
        res.json(resultCopy);
      }
    });
  });
});
//应用复制
router.get("/copy", function (req, res, next) {
  var params = req.query;
  params && params.id && !params._id && (params._id = params.id); //TODO 需要删除

  nedb.findOne(params).then((result) => {
    var data = result.data;
    let oldId = data._id;
    delete data.id;
    delete data._id;
    data.applicationName = params.applicationName;

    nedb.insert(data).then((resultCopy) => {
      if (resultCopy.data) {
        var doc = resultCopy.data;
        var docStr = JSON.stringify(doc).replace(new RegExp(oldId, "g"), doc._id);
        var docReplace = JSON.parse(docStr);
        nedb.update(docReplace).then((result1) => {
          if (result1.code == nedb.CODE_SUCCESS) {
            copyTemp(`./appStatic/app/${oldId}`, `./appStatic/app/${doc._id}`);
            result1.message = "应用复制成功";
          }
          res.json(result1);
        });
      } else {
        res.json(resultCopy);
      }
    });
  });
});

//应用发布
router.get("/publish", function (req, res, next) {
  var params = req.query;
  params && params.id && !params._id && (params._id = params.id); //TODO 需要删除
  nedb.exec((db) => {
    db.update({ _id: params._id }, { $set: { isRelease: 1 } }, (error, doc) => {
      console.log(error, doc);

      var code = nedb.CODE_SUCCESS;
      var message = "应用发布成功";

      if (error) {
        code = nedb.CODE_ERROR;
        message = "应用发布失败";
      }
      if (!(doc > 0)) {
        code = nedb.CODE_ERROR;
        message = "没有可发布的应用";
      }

      res.json({
        code,
        message,
        error
      });
    });
  });
});
//取消发布应用
router.get("/cancel/publish", function (req, res, next) {
  var params = req.query;
  params && params.id && !params._id && (params._id = params.id); //TODO 需要删除
  nedb.exec((db) => {
    db.update({ _id: params._id }, { $set: { isRelease: 0 } }, (error, doc) => {
      console.log(error, doc);
      var code = nedb.CODE_SUCCESS;
      var message = "应用取消发布成功";
      if (error) {
        code = nedb.CODE_ERROR;
        message = "应用取消发布失败";
      }
      if (!(doc > 0)) {
        code = nedb.CODE_ERROR;
        message = "没有可取消发布的应用";
      }

      res.json({
        code,
        message,
        error
      });
    });
  });
});
//删除应用资源文件
router.delete("/remove", function (req, res, next) {
  try {
    var query = req.query || {};
    let dirParent = "./appStatic";
    let dir = query.path;
    var err = !fs.existsSync(`${dirParent}/${dir}`) ? "文件不存在" : fs.rmSync(`${dirParent}/${dir}`);
    res.json({
      code: !err ? 200 : -1,
      message: !err ? "文件删除成功" : err || "文件删除失败"
      // data: `${dirParent}/${dir}`,
    });
  } catch (error) {
    res.json({
      code: -1,
      message: "文件删除异常",
      error: error.message
    });
  }
});

//查询列表数据
router.get("/page", function (req, res, next) {
  var query = req.query || {};
  // current=1&size=14&applicationName=&descs=update_time
  let limit = (query.size || 100) - 0;
  let skip = (query.current || 1) - 1;
  var params = {
    filter: {},
    skip: skip * limit, //分页
    limit: limit, //分页
    sort: {}
  };
  if (query.applicationName) {
    //过滤
    params.filter.applicationName = query.applicationName;
  }
  if (query.descs) {
    //排序
    params.sort[query.descs] = -1;
  }
  nedb.find(params).then((result) => {
    // if (result && result.data) {
    //   result.data = { ...result.data, applicationConfigJson: result.data }; // TODO 需要删除
    // }

    (((result || {}).data || {}).records || []).map((item) => {
      delete item.pages;
      delete item.style;
      item.previewImg = `./app/${item._id}/app-pre.png?${item.previewImg}`;
      return item;
    });

    res.json(result);
  });
});

//查询单条数据
router.get("/:id", function (req, res, next) {
  var params = req.params;
  nedb.findOne(params).then((result) => {
    if (result && result.data) {
      result.data = { ...result.data, applicationConfigJson: result.data }; // TODO 需要删除
    }
    res.json(result);
  });
});

//保存数据
router.post("/saveOrUpdate", function (req, res, next) {
  var params = req.body;
  if (params) {
    let t = new Date();
    params.update_time = t.getTime();
    params.updateTime = t.toLocaleString();
    params.updateUserName = "测试用户(更新)";
    if (!params.id || !params._id) {
      params.createTime = t.toLocaleString();
      params.createUserName = "测试用户(创建)";
      params.updateUserName = params.createUserName;
    }
  }
  let previewImg = params.previewImg || ""; //缓存预览图
  params.previewImg = "t=" + Date.now(); //更新预览图更新标识
  nedb[params && params.id ? "update" : "insert"](params).then((result) => {
    try {
      if (!params.previewImg) {
        console.error("没有预览图");
      }
      let id = (result.data || {})._id;
      if (id) {
        let dir = `./appStatic/app/${id}`;
        if (!fs.existsSync(dir)) {
          fs.mkdirSync(dir, { recursive: true });
        }
        let base64 = previewImg.replace(/^data:image\/\w+;base64,/, ""); //去掉图⽚base64码前⾯部分data:im
        let dataBuffer = Buffer.from(base64, "base64");
        let data = fs.writeFileSync(`${dir}/app-pre.png`, dataBuffer);
        console.log("保存预览图片", data);
      }
    } catch (error) {
      console.error("[保存预览图片异常]", error);
    }
    res.json(result);
  });
});

//删除单条数据
router.post("/delete/:id", function (req, res, next) {
  var params = req.params;
  nedb.remove(params).then((result) => {
    try {
      let dir = `./appStatic/app/${params.id}`;
      fs.existsSync(dir) && fs.rmdirSync(dir, { recursive: true }); //删除应用对应目录
    } catch (error) {
      console.error(["删除应用目录异常"], error);
    }
    res.json(result);
  });
});

export default router;
